Skip to content

qtvcp: exit cleanly on SIGTERM/SIGINT#4078

Merged
c-morley merged 1 commit into
LinuxCNC:masterfrom
grandixximo:fix/qtvcp-sigterm-clean-exit
May 30, 2026
Merged

qtvcp: exit cleanly on SIGTERM/SIGINT#4078
c-morley merged 1 commit into
LinuxCNC:masterfrom
grandixximo:fix/qtvcp-sigterm-clean-exit

Conversation

@grandixximo
Copy link
Copy Markdown
Contributor

qtvcp screens (qtdragon etc.) ignored SIGTERM and SIGINT: Python signal handlers do not run while QApplication.exec() blocks in the Qt C++ loop, so the process never exited and ui-smoke teardown escalated to SIGKILL.

This quits the Qt loop directly on SIGTERM and SIGINT, and adds a low-frequency QTimer so the interpreter periodically regains control to deliver the signal. The existing post-exec shutdown() still runs the cleanup. The X-button "are you sure?" confirmation dialog is left intact for interactive close; only the terminate signals bypass it, which is correct for SIGTERM.

Part of the SIGTERM clean-shutdown work discussed in #4054.

qtvcp registered self.shutdown as the SIGTERM/SIGINT handler, but two
things stopped it working: Qt's C++ event loop (APP.exec()) does not
return to Python often enough to run Python signal handlers, and
shutdown() cleans up without quitting the loop, so even when reached the
process kept running. A caller tearing qtvcp down therefore had to
escalate to SIGKILL.

Quit the event loop on the signal (APP.quit()) so APP.exec() returns and
the existing post-exec shutdown() runs the normal cleanup once, and add a
periodic no-op QTimer so the interpreter gets a chance to run the signal
handler during exec(). Quitting the loop bypasses the window-close
confirmation dialog, which is correct for a terminate request and leaves
that interactive feature untouched.

Fixes the hang for all qtvcp screens (qtdragon, qtplasmac, ...). Verified
qtdragon exits cleanly on SIGTERM and SIGINT.

Surfaced by the ui-smoke tests (PR LinuxCNC#4054).
@hansu hansu added the qtvcp label May 30, 2026
@c-morley c-morley merged commit 7351e0e into LinuxCNC:master May 30, 2026
15 checks passed
grandixximo added a commit to grandixximo/linuxcnc that referenced this pull request Jun 1, 2026
Adds a quit-path smoke test per GUI that boots the GUI, waits for the
NML task to come up, sends SIGTERM to the GUI process alone, and asserts
the GUI exits on its own within a short grace. This guards the
clean-shutdown handlers: a GUI that absorbs SIGTERM and has to be
SIGKILLed fails the test.

The new _lib/quit-launch.sh shares the headless environment (software
GL + audio silencing) with launch.sh by sourcing a new
_lib/launch-env.sh rather than copying it, so the two launchers cannot
drift apart. Results go through _lib/checkresult-quit.sh (pass on
UI_SMOKE_QUIT_OK). The GUI process is identified by matching a python
argv[0], so the linuxcnc launcher and xvfb-run wrappers that also carry
the GUI name on their command line are not mistaken for it. Per-GUI
dirs: touchy-quit, gmoccapy-quit, qtdragon-quit.

The qtdragon quit test needs the same CI workarounds the qtdragon smoke
test already carries (writable config mirror with a patched LOG_FILE,
the offscreen Qt platform, and the QtWebEngine import shim). Those move
out of qtdragon/test.sh into _lib/qtdragon-prepare.sh, sourced by both
qtdragon test.sh files, so the quit test reuses them instead of leaving
qtvcp to crash on startup.

Requires the SIGTERM handlers in LinuxCNC#4076 (gmoccapy), LinuxCNC#4077 (touchy) and
LinuxCNC#4078 (qtvcp); without them the GUIs ignore SIGTERM and these tests
fail by design.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants